package com.atguigu.springcloud.feign;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xiaolong
 * @version 1.0
 * @description: Feign 支持请求拦截器，在发送请求前，对发送的模板进行操作，例如设置请求头等属性。
 * @date 2021/10/14 10:45
 */
@Configuration
@ComponentScan("com.atguigu.springcloud.feign.*")
@EnableFeignClients("com.atguigu.springcloud.feign.*")   //使用激活openfeign
public class FeignClientConfig implements RequestInterceptor {

    @Value("response.webHeader:G-Rpc")
    private String rpcHeader;

    @Value("spring.application.name")
    private String applicationName;


    //设置请求头等属性
    @Override
    public void apply(RequestTemplate request) {
//        request.header(rpcHeader,applicationName);
//        try {
//            Map<String, String> map = AuthThreadLocal.get();
//            String gAuth = map.get(AuthThreadLocal.G_AUTH);
//            String authorization = map.get(AuthThreadLocal.AUTHORIZATTON);
//            redirect(request,map.get("REAL_URL"));
//            request.header("g-auth",gAuth);
//            request.header("Authorization",authorization);
//        }finally {
//            AuthThreadLocal.remove();
//        }

        //获取当前传播的对象--我们有的时候会在service层获取request填充一些诸如用户名和IP地址等信息，这个时候如果不想从Controller层传request，可以在service直接使用
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest request1 = ((ServletRequestAttributes) requestAttributes).getRequest();
            if (request1 != null) {
                //设置header属性：requestTemplate.header(name, values);
                Enumeration<String> headerNames = request1.getHeaderNames();
                if (headerNames != null) {
                    while (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String values = request1.getHeader(name);
                        request.header(name, values);
                    }
                }

                //设置param属性：requestTemplate.query(name, values);
                Enumeration<String> paramNames = request1.getParameterNames();
                if (paramNames != null) {
                    Map map = new HashMap();
                    while (paramNames.hasMoreElements()) {
                        String name = paramNames.nextElement();
                        String values = request1.getParameter(name);
                        request.query(name, values);
                    }
                }
            }
        }


    }


    /**
     * @param
     * @description: 重定向request host，仅支持负载均衡模式
     */
    private void redirect(RequestTemplate request, String uriPrefix) {
        String url = request.url();
        int index = request.url().indexOf("$");
        if (index < 0) {
            return;
        }
        while (url.startsWith("/")) {
            url = url.substring(1);
        }
        String code = "";
        index = url.indexOf("$");
        String temp = url.substring(index + 1);
        int indexOf = temp.indexOf("/");
        if (indexOf >= 0) {
            code = temp.substring(0, indexOf);
        }
        url.replace("$" + code, "");

        if (!url.startsWith("/")) {
            url = "/" + url;
        }
        if (!"".equals(code)) {
            url = "-" + code + url;
        }
        StringBuffer buider = new StringBuffer(uriPrefix + url);
        Field field = null;

        try {
            field = RequestTemplate.class.getDeclaredField("url");
            field.setAccessible(true);
            field.set(request, buider);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
